﻿Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Globalization
Imports System.Reflection
Imports System.Text
Imports System.Windows.Forms
Imports System.Windows.Forms.Design
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Compiler

Namespace System.Workflow.ComponentModel.Design
    Friend NotInheritable Class ActivityBindForm
        Inherits Form
        ' Methods
        Public Sub New(ByVal serviceProvider As IServiceProvider, ByVal context As ITypeDescriptorContext)
            Me.context = context
            Me.serviceProvider = serviceProvider
            Me.InitializeComponent
            Me.createProperty.Checked = True
            Me.helpTextBox.Multiline = True
            Dim service As IUIService = DirectCast(Me.serviceProvider.GetService(GetType(IUIService)), IUIService)
            If (Not service Is Nothing) Then
                Me.Font = DirectCast(service.Styles.Item("DialogFont"), Font)
            End If
            Dim manager As New ComponentResourceManager(GetType(ActivityBindForm))
            Me.ActivityBindDialogTitleFormat = manager.GetString("ActivityBindDialogTitleFormat")
            Me.PropertyAssignableFormat = manager.GetString("PropertyAssignableFormat")
            Me.DescriptionFormat = manager.GetString("DescriptionFormat")
            Me.EditIndex = manager.GetString("EditIndex")
            Me.PleaseSelectCorrectActivityProperty = manager.GetString("PleaseSelectCorrectActivityProperty")
            Me.PleaseSelectActivityProperty = manager.GetString("PleaseSelectActivityProperty")
            Me.IncorrectIndexChange = manager.GetString("IncorrectIndexChange")
            Me.CreateNewMemberHelpFormat = manager.GetString("CreateNewMemberHelpFormat")
            Me.memberTypes = New ImageList
            Me.memberTypes.ImageStream = DirectCast(manager.GetObject("memberTypes.ImageStream"), ImageListStreamer)
            Me.memberTypes.TransparentColor = AmbientTheme.TransparentColor
        End Sub

        Private Sub ActivityBindForm_HelpButtonClicked(ByVal sender As Object, ByVal e As CancelEventArgs)
            e.Cancel = True
            Me.GetHelp
        End Sub

        Private Sub ActivityBindForm_Load(ByVal sender As Object, ByVal e As EventArgs)
            Me.Text = String.Format(CultureInfo.CurrentCulture, Me.ActivityBindDialogTitleFormat, New Object() { Me.context.PropertyDescriptor.Name })
            Dim customProperties As List([Of] CustomProperty) = CustomActivityDesignerHelper.GetCustomProperties(Me.context)
            If TypeOf Me.context.PropertyDescriptor Is DynamicPropertyDescriptor Then
                Me.boundType = PropertyDescriptorUtils.GetBaseType(Me.context.PropertyDescriptor, PropertyDescriptorUtils.GetComponent(Me.context), Me.serviceProvider)
            End If
            If (Not Me.boundType Is Nothing) Then
                Dim provider As ITypeProvider = [TryCast](Me.serviceProvider.GetService(GetType(ITypeProvider)),ITypeProvider)
                If (Not provider Is Nothing) Then
                    Dim type As Type = provider.GetType(Me.boundType.FullName, False)
                    Me.boundType = If((Not type Is Nothing), type, Me.boundType)
                End If
            End If
            Me.workflowOutline = New ActivityBindFormWorkflowOutline(Me.serviceProvider, Me)
            Me.dummyPanel.BorderStyle = BorderStyle.None
            Me.dummyPanel.SuspendLayout
            Me.dummyPanel.Controls.Add(Me.workflowOutline)
            Me.workflowOutline.Location = New Point(3, 3)
            Me.workflowOutline.Size = New Size(&HC7, &H15F)
            Me.workflowOutline.Dock = DockStyle.Fill
            Me.dummyPanel.ResumeLayout(False)
            Me.workflowOutline.AddMemberKindImages(Me.memberTypes)
            Me.workflowOutline.ReloadWorkflowOutline
            Me.workflowOutline.ExpandRootNode
            Dim component As Activity = [TryCast](PropertyDescriptorUtils.GetComponent(Me.context),Activity)
            If (component Is Nothing) Then
                Dim service As IReferenceService = [TryCast](Me.context.GetService(GetType(IReferenceService)),IReferenceService)
                If (Not service Is Nothing) Then
                    component = [TryCast](service.GetComponent(Me.context.Instance),Activity)
                End If
            End If
            Dim bind As ActivityBind = [TryCast](Me.context.PropertyDescriptor.GetValue(Me.context.Instance),ActivityBind)
            If ((Not component Is Nothing) AndAlso (Not bind Is Nothing)) Then
                Dim activity As Activity = Helpers.ParseActivity(Helpers.GetRootActivity(component), bind.Name)
                If (Not activity Is Nothing) Then
                    Me.workflowOutline.SelectActivity(activity, Me.ParseStringPath(Me.GetActivityType(activity), bind.Path))
                End If
            End If
            If (Not customProperties Is Nothing) Then
                Dim list2 As New List([Of] String)
                Dim property As CustomProperty
                For Each property In customProperties
                    list2.Add([property].Name)
                Next
                Me.memberNameTextBox.Text = DesignerHelpers.GenerateUniqueIdentifier(Me.serviceProvider, (component.Name & "_" & Me.context.PropertyDescriptor.Name), list2.ToArray)
            End If
            Me.newMemberHelpTextBox.Lines = String.Format(CultureInfo.CurrentCulture, Me.CreateNewMemberHelpFormat, New Object() { Me.GetSimpleTypeFullName(Me.boundType) }).Split(New Char() { ChrW(10) })
        End Sub

        Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As EventArgs)
            MyBase.DialogResult = DialogResult.Cancel
        End Sub

        Private Function ConstructIndexString(ByVal getterMethod As MethodInfo) As String
            Dim builder As New StringBuilder
            Dim parameters As ParameterInfo() = getterMethod.GetParameters
            If ((Not parameters Is Nothing) AndAlso (parameters.Length > 0)) Then
                builder.Append("[")
                Dim i As Integer
                For i = 0 To parameters.Length - 1
                    Dim info As ParameterInfo = parameters(i)
                    Dim indexerString As String = Me.GetIndexerString(info.ParameterType)
                    If (indexerString Is Nothing) Then
                        Return Nothing
                    End If
                    builder.Append(indexerString)
                    If (i < (parameters.Length - 1)) Then
                        builder.Append(",")
                    End If
                Next i
                builder.Append("]")
            End If
            Return builder.ToString
        End Function

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            If (disposing AndAlso (Not Me.components Is Nothing)) Then
                Me.components.Dispose
            End If
            MyBase.Dispose(disposing)
        End Sub

        Private Function GetActivityType(ByVal activity As Activity) As Type
            Dim type As Type = Nothing
            Dim service As IDesignerHost = [TryCast](Me.serviceProvider.GetService(GetType(IDesignerHost)),IDesignerHost)
            Dim loader As WorkflowDesignerLoader = [TryCast](Me.serviceProvider.GetService(GetType(WorkflowDesignerLoader)),WorkflowDesignerLoader)
            If (((Not service Is Nothing) AndAlso (Not loader Is Nothing)) AndAlso (activity.Parent Is Nothing)) Then
                Dim provider As ITypeProvider = [TryCast](Me.serviceProvider.GetService(GetType(ITypeProvider)),ITypeProvider)
                If (Not provider Is Nothing) Then
                    type = provider.GetType(service.RootComponentClassName, False)
                End If
            End If
            If (type Is Nothing) Then
                type = activity.GetType
            End If
            Return type
        End Function

        Private Function GetArraySubProperties(ByVal propertyType As Type, ByVal currentPath As String) As PathInfo()
            Dim list As New List([Of] PathInfo)
            If (Not propertyType Is GetType(String)) Then
                Dim list2 As New List([Of] MethodInfo)
                Dim defaultMembers As MemberInfo() = Nothing
                Try 
                    defaultMembers = propertyType.GetDefaultMembers
                Catch exception1 As ArgumentException
                End Try
                If ((Not defaultMembers Is Nothing) AndAlso (defaultMembers.Length > 0)) Then
                    Dim info As MemberInfo
                    For Each info In defaultMembers
                        If TypeOf info Is PropertyInfo Then
                            list2.Add([TryCast](info,PropertyInfo).GetGetMethod)
                        End If
                    Next
                End If
                If propertyType.IsArray Then
                    Dim member As MemberInfo() = propertyType.GetMember("Get")
                    If ((Not member Is Nothing) AndAlso (member.Length > 0)) Then
                        Dim info2 As MemberInfo
                        For Each info2 In member
                            If TypeOf info2 Is MethodInfo Then
                                list2.Add([TryCast](info2,MethodInfo))
                            End If
                        Next
                    End If
                End If
                Dim info3 As MethodInfo
                For Each info3 In list2
                    Dim str As String = Me.ConstructIndexString(info3)
                    If (Not str Is Nothing) Then
                        list.Add(New PathInfo((currentPath & str), info3, info3.ReturnType))
                    End If
                Next
            End If
            Return list.ToArray
        End Function

        Private Sub GetHelp()
            DesignerHelpers.ShowHelpFromKeyword(Me.serviceProvider, (GetType(ActivityBindForm).FullName & ".UI"))
        End Sub

        Private Function GetIndexerString(ByVal indexType As Type) As String
            Dim obj2 As Object = Nothing
            If ActivityBindForm.IsTypePrimitive(indexType) Then
                Try 
                    obj2 = Activator.CreateInstance(indexType)
                Catch obj1 As Object
                    obj2 = Nothing
                End Try
            ElseIf (indexType Is GetType(String)) Then
                obj2 = """<name>"""
            End If
            If (obj2 Is Nothing) Then
                Return Nothing
            End If
            Return obj2.ToString
        End Function

        Private Function GetMemberDescription(ByVal member As MemberInfo) As String
            Dim customAttributes As Object() = member.GetCustomAttributes(GetType(DescriptionAttribute), False)
            If ((customAttributes Is Nothing) OrElse (customAttributes.Length <= 0)) Then
                Return String.Empty
            End If
            Dim attribute As DescriptionAttribute = [TryCast](customAttributes(0),DescriptionAttribute)
            If (attribute Is Nothing) Then
                Return String.Empty
            End If
            Return attribute.Description
        End Function

        Private Function GetProperties(ByVal type As Type) As PropertyInfo()
            Dim list As New List([Of] PropertyInfo)
            list.AddRange(type.GetProperties((BindingFlags.FlattenHierarchy Or (BindingFlags.Public Or (BindingFlags.Static Or BindingFlags.Instance)))))
            If type.IsInterface Then
                Dim type2 As Type
                For Each type2 In type.GetInterfaces
                    list.AddRange(type2.GetProperties((BindingFlags.FlattenHierarchy Or (BindingFlags.Public Or BindingFlags.Instance))))
                Next
            End If
            Return list.ToArray
        End Function

        Private Function GetSimpleTypeFullName(ByVal type As Type) As String
            If (type Is Nothing) Then
                Return String.Empty
            End If
            Dim builder As New StringBuilder(type.FullName)
            Dim stack As New Stack([Of] Type)
            stack.Push(type)
            Do While (stack.Count > 0)
                type = stack.Pop
                Do While type.IsArray
                    type = type.GetElementType
                Loop
                If (type.IsGenericType AndAlso Not type.IsGenericTypeDefinition) Then
                    Dim type2 As Type
                    For Each type2 In type.GetGenericArguments
                        builder.Replace(("[" & type2.AssemblyQualifiedName & "]"), Me.GetSimpleTypeFullName(type2))
                        stack.Push(type2)
                    Next
                End If
            Loop
            Return builder.ToString
        End Function

        Private Function GetSubPropertiesOnType(ByVal typeToGetPropertiesOn As Type, ByVal currentPath As String) As PathInfo()
            Dim list As New List([Of] PathInfo)
            If ((Not typeToGetPropertiesOn Is GetType(String)) AndAlso (Not TypeProvider.IsAssignable(GetType(Delegate), typeToGetPropertiesOn) OrElse Me.boundType.IsSubclassOf(GetType(Delegate)))) Then
                currentPath = If(String.IsNullOrEmpty(currentPath), String.Empty, (currentPath & "."))
                Dim service As ITypeProvider = [TryCast](Me.serviceProvider.GetService(GetType(ITypeProvider)),ITypeProvider)
                Dim info As PropertyInfo
                For Each info In Me.GetProperties(typeToGetPropertiesOn)
                    Dim getMethod As MethodInfo = info.GetGetMethod
                    Dim memberType As Type = BindHelpers.GetMemberType(info)
                    If (Not memberType Is Nothing) Then
                        If (Not service Is Nothing) Then
                            Dim type As Type = service.GetType(memberType.FullName, False)
                            memberType = If((Not type Is Nothing), type, memberType)
                        End If
                        If (((Me.IsPropertyBrowsable(info) AndAlso (Not getMethod Is Nothing)) AndAlso (Not memberType Is Nothing)) AndAlso ((Not ActivityBindForm.IsTypePrimitive(memberType) OrElse TypeProvider.IsAssignable(Me.boundType, memberType)) AndAlso ((Me.boundType Is GetType(Object)) OrElse (Not memberType Is GetType(Object))))) Then
                            Dim name As String = info.Name
                            name = (currentPath & name & Me.ConstructIndexString(getMethod))
                            list.Add(New PathInfo(name, info, memberType))
                            list.AddRange(Me.GetArraySubProperties(memberType, name))
                        End If
                    End If
                Next
                Dim info3 As FieldInfo
                For Each info3 In typeToGetPropertiesOn.GetFields((BindingFlags.FlattenHierarchy Or (BindingFlags.Public Or (BindingFlags.Static Or BindingFlags.Instance))))
                    Dim fromType As Type = BindHelpers.GetMemberType(info3)
                    If ((Not fromType Is Nothing) AndAlso Not TypeProvider.IsAssignable(GetType(DependencyProperty), fromType)) Then
                        If (Not service Is Nothing) Then
                            Dim type4 As Type = service.GetType(fromType.FullName, False)
                            fromType = If((Not type4 Is Nothing), type4, fromType)
                        End If
                        If (((Me.IsPropertyBrowsable(info3) AndAlso (Not fromType Is Nothing)) AndAlso (Not ActivityBindForm.IsTypePrimitive(fromType) OrElse TypeProvider.IsAssignable(Me.boundType, fromType))) AndAlso (((Me.boundType Is GetType(Object)) OrElse (Not fromType Is GetType(Object))) AndAlso (TypeProvider.IsAssignable(GetType(Delegate), Me.boundType) OrElse Not TypeProvider.IsAssignable(GetType(Delegate), fromType)))) Then
                            Dim path As String = (currentPath & info3.Name)
                            list.Add(New PathInfo(path, info3, BindHelpers.GetMemberType(info3)))
                            list.AddRange(Me.GetArraySubProperties(fromType, path))
                        End If
                    End If
                Next
                If Me.boundType.IsSubclassOf(GetType(Delegate)) Then
                    Dim info4 As EventInfo
                    For Each info4 In typeToGetPropertiesOn.GetEvents((BindingFlags.FlattenHierarchy Or (BindingFlags.Public Or BindingFlags.Instance)))
                        Dim type5 As Type = BindHelpers.GetMemberType(info4)
                        If (Not type5 Is Nothing) Then
                            If (Not service Is Nothing) Then
                                Dim type6 As Type = service.GetType(type5.FullName, False)
                                type5 = If((Not type6 Is Nothing), type6, type5)
                            End If
                            If ((Me.IsPropertyBrowsable(info4) AndAlso (Not type5 Is Nothing)) AndAlso TypeProvider.IsAssignable(Me.boundType, type5)) Then
                                list.Add(New PathInfo((currentPath & info4.Name), info4, type5))
                            End If
                        End If
                    Next
                End If
            End If
            Return list.ToArray
        End Function

        Private Sub InitializeComponent()
            Dim manager As New ComponentResourceManager(GetType(ActivityBindForm))
            Me.dummyPanel = New Panel
            Me.cancelButton = New Button
            Me.OKButton = New Button
            Me.buttonTableLayoutPanel = New TableLayoutPanel
            Me.helpTextBox = New TextBox
            Me.createField = New RadioButton
            Me.createProperty = New RadioButton
            Me.groupBox1 = New GroupBox
            Me.bindTabControl = New TabControl
            Me.existingMemberPage = New TabPage
            Me.newMemberPage = New TabPage
            Me.newMemberHelpTextBox = New TextBox
            Me.memberNameLabel = New Label
            Me.memberNameTextBox = New TextBox
            Me.buttonTableLayoutPanel.SuspendLayout
            Me.groupBox1.SuspendLayout
            Me.bindTabControl.SuspendLayout
            Me.existingMemberPage.SuspendLayout
            Me.newMemberPage.SuspendLayout
            MyBase.SuspendLayout
            manager.ApplyResources(Me.dummyPanel, "dummyPanel")
            Me.dummyPanel.BorderStyle = BorderStyle.FixedSingle
            Me.dummyPanel.Name = "dummyPanel"
            Me.cancelButton.DialogResult = DialogResult.Cancel
            manager.ApplyResources(Me.cancelButton, "cancelButton")
            Me.cancelButton.Name = "cancelButton"
            Me.cancelButton.UseVisualStyleBackColor = True
            AddHandler Me.cancelButton.Click, New EventHandler(AddressOf Me.cancelButton_Click)
            manager.ApplyResources(Me.OKButton, "OKButton")
            Me.OKButton.Name = "OKButton"
            Me.OKButton.UseVisualStyleBackColor = True
            AddHandler Me.OKButton.Click, New EventHandler(AddressOf Me.OKButton_Click)
            manager.ApplyResources(Me.buttonTableLayoutPanel, "buttonTableLayoutPanel")
            Me.buttonTableLayoutPanel.Controls.Add(Me.OKButton, 0, 0)
            Me.buttonTableLayoutPanel.Controls.Add(Me.cancelButton, 1, 0)
            Me.buttonTableLayoutPanel.Name = "buttonTableLayoutPanel"
            manager.ApplyResources(Me.helpTextBox, "helpTextBox")
            Me.helpTextBox.Name = "helpTextBox"
            Me.helpTextBox.ReadOnly = True
            manager.ApplyResources(Me.createField, "createField")
            Me.createField.Checked = True
            Me.createField.Name = "createField"
            Me.createField.TabStop = True
            Me.createField.UseVisualStyleBackColor = True
            manager.ApplyResources(Me.createProperty, "createProperty")
            Me.createProperty.Name = "createProperty"
            Me.createProperty.UseVisualStyleBackColor = True
            manager.ApplyResources(Me.groupBox1, "groupBox1")
            Me.groupBox1.Controls.Add(Me.createField)
            Me.groupBox1.Controls.Add(Me.createProperty)
            Me.groupBox1.Name = "groupBox1"
            Me.groupBox1.TabStop = False
            manager.ApplyResources(Me.bindTabControl, "bindTabControl")
            Me.bindTabControl.Controls.Add(Me.existingMemberPage)
            Me.bindTabControl.Controls.Add(Me.newMemberPage)
            Me.bindTabControl.Name = "bindTabControl"
            Me.bindTabControl.SelectedIndex = 0
            Me.existingMemberPage.Controls.Add(Me.dummyPanel)
            Me.existingMemberPage.Controls.Add(Me.helpTextBox)
            manager.ApplyResources(Me.existingMemberPage, "existingMemberPage")
            Me.existingMemberPage.Name = "existingMemberPage"
            Me.existingMemberPage.UseVisualStyleBackColor = True
            Me.newMemberPage.Controls.Add(Me.memberNameLabel)
            Me.newMemberPage.Controls.Add(Me.memberNameTextBox)
            Me.newMemberPage.Controls.Add(Me.groupBox1)
            Me.newMemberPage.Controls.Add(Me.newMemberHelpTextBox)
            manager.ApplyResources(Me.newMemberPage, "newMemberPage")
            Me.newMemberPage.Name = "newMemberPage"
            Me.newMemberPage.UseVisualStyleBackColor = True
            manager.ApplyResources(Me.newMemberHelpTextBox, "newMemberHelpTextBox")
            Me.newMemberHelpTextBox.Name = "newMemberHelpTextBox"
            Me.newMemberHelpTextBox.ReadOnly = True
            manager.ApplyResources(Me.memberNameLabel, "memberNameLabel")
            Me.memberNameLabel.Name = "memberNameLabel"
            manager.ApplyResources(Me.memberNameTextBox, "memberNameTextBox")
            Me.memberNameTextBox.Name = "memberNameTextBox"
            MyBase.AcceptButton = Me.OKButton
            manager.ApplyResources(Me, "$this")
            MyBase.AutoScaleMode = AutoScaleMode.Font
            MyBase.CancelButton = Me.cancelButton
            MyBase.Controls.Add(Me.bindTabControl)
            MyBase.Controls.Add(Me.buttonTableLayoutPanel)
            MyBase.HelpButton = True
            MyBase.MaximizeBox = False
            MyBase.MinimizeBox = False
            MyBase.Name = "ActivityBindForm"
            MyBase.ShowIcon = False
            MyBase.ShowInTaskbar = False
            MyBase.SizeGripStyle = SizeGripStyle.Show
            AddHandler MyBase.HelpButtonClicked, New CancelEventHandler(AddressOf Me.ActivityBindForm_HelpButtonClicked)
            AddHandler MyBase.Load, New EventHandler(AddressOf Me.ActivityBindForm_Load)
            Me.buttonTableLayoutPanel.ResumeLayout(False)
            Me.groupBox1.ResumeLayout(False)
            Me.groupBox1.PerformLayout
            Me.bindTabControl.ResumeLayout(False)
            Me.existingMemberPage.ResumeLayout(False)
            Me.existingMemberPage.PerformLayout
            Me.newMemberPage.ResumeLayout(False)
            Me.newMemberPage.PerformLayout
            MyBase.ResumeLayout(False)
            MyBase.PerformLayout
        End Sub

        Private Function IsPropertyBrowsable(ByVal [property] As MemberInfo) As Boolean
            Dim customAttributes As Object() = [property].GetCustomAttributes(GetType(BrowsableAttribute), False)
            If (customAttributes.Length > 0) Then
                Dim attribute As BrowsableAttribute = [TryCast](customAttributes(0),BrowsableAttribute)
                If (Not attribute Is Nothing) Then
                    Return attribute.Browsable
                End If
                Dim attribute2 As AttributeInfoAttribute = [TryCast](customAttributes(0),AttributeInfoAttribute)
                If (Not attribute2 Is Nothing) Then
                    Dim argumentValues As ReadOnlyCollection([Of] Object) = attribute2.AttributeInfo.ArgumentValues
                    If (argumentValues.Count > 0) Then
                        Return Convert.ToBoolean(argumentValues.Item(0), CultureInfo.InvariantCulture)
                    End If
                End If
            End If
            Return True
        End Function

        Private Shared Function IsTypePrimitive(ByVal type As Type) As Boolean
            If (((Not type.IsPrimitive AndAlso Not type.IsEnum) AndAlso ((Not type Is GetType(Guid)) AndAlso (Not type Is GetType(IntPtr)))) AndAlso ((Not type Is GetType(String)) AndAlso (Not type Is GetType(DateTime)))) Then
                Return (type Is GetType(TimeSpan))
            End If
            Return True
        End Function

        Private Sub OKButton_Click(ByVal sender As Object, ByVal e As EventArgs)
            MyBase.DialogResult = DialogResult.None
            Me.createNew = (Me.bindTabControl.SelectedIndex <> Me.bindTabControl.TabPages.IndexOf(Me.existingMemberPage))
            If Me.createNew Then
                Me.createNewProperty = Me.createProperty.Checked
                Me.newMemberName = Me.memberNameTextBox.Text
                MyBase.DialogResult = Me.ValidateNewMemberBind(Me.newMemberName)
            Else
                MyBase.DialogResult = Me.ValidateExistingPropertyBind
            End If
        End Sub

        Protected Overrides Sub OnHelpRequested(ByVal e As HelpEventArgs)
            e.Handled = True
            Me.GetHelp
        End Sub

        Private Function ParseStringPath(ByVal activityType As Type, ByVal path As String) As List([Of] PathInfo)
            If String.IsNullOrEmpty(path) Then
                Return Nothing
            End If
            Dim pathInfoList As New List([Of] PathInfo)
            Dim walker As New PathWalker
            Dim finalEventArgs As PathMemberInfoEventArgs = Nothing
            Dim errorEventArgs As PathErrorInfoEventArgs = Nothing
            walker.MemberFound = DirectCast(Delegate.Combine(walker.MemberFound, Function (ByVal sender As Object, ByVal eventArgs As PathMemberInfoEventArgs) 
                finalEventArgs = eventArgs
                pathInfoList.Add(New PathInfo(eventArgs.Path, eventArgs.MemberInfo, BindHelpers.GetMemberType(eventArgs.MemberInfo)))
            End Function), EventHandler([Of] PathMemberInfoEventArgs))
            walker.PathErrorFound = DirectCast(Delegate.Combine(walker.PathErrorFound, Function (ByVal sender As Object, ByVal eventArgs As PathErrorInfoEventArgs) 
                errorEventArgs = eventArgs
            End Function), EventHandler([Of] PathErrorInfoEventArgs))
            walker.TryWalkPropertyPath(activityType, path)
            Return pathInfoList
        End Function

        Private Function PopulateAutoCompleteList(ByVal activity As Activity, ByVal path As PathInfo) As List([Of] PathInfo)
            Dim list As New List([Of] PathInfo)
            Dim activityType As Type = Me.GetActivityType(activity)
            Dim collection As PathInfo() = If((Not activityType Is Nothing), Me.ProcessPaths(activityType, path), Nothing)
            If (Not collection Is Nothing) Then
                list.AddRange(collection)
            End If
            Return list
        End Function

        Private Function ProcessPaths(ByVal activityType As Type, ByVal topProperty As PathInfo) As PathInfo()
            Dim list As New List([Of] PathInfo)
            If (topProperty Is Nothing) Then
                list.AddRange(Me.GetSubPropertiesOnType(activityType, String.Empty))
            Else
                list.AddRange(Me.GetSubPropertiesOnType(topProperty.PropertyType, topProperty.Path))
            End If
            Return list.ToArray
        End Function

        Private Sub SelectedActivityChanged(ByVal activity As Activity, ByVal memberPathInfo As PathInfo, ByVal path As String)
            Dim str As String = String.Empty
            Dim simpleTypeFullName As String = Me.GetSimpleTypeFullName(Me.boundType)
            If (Not memberPathInfo Is Nothing) Then
                If ((path Is Nothing) OrElse (path.Length = 0)) Then
                    str = String.Format(CultureInfo.CurrentCulture, Me.PleaseSelectActivityProperty, New Object() { simpleTypeFullName })
                Else
                    MemberActivityBindTreeNode.MemberName(memberPathInfo.Path)
                    Dim str3 As String = Me.GetSimpleTypeFullName(memberPathInfo.PropertyType)
                    Dim memberDescription As String = Me.GetMemberDescription(memberPathInfo.MemberInfo)
                    If TypeProvider.IsAssignable(Me.boundType, memberPathInfo.PropertyType) Then
                        str = (String.Format(CultureInfo.CurrentCulture, Me.PropertyAssignableFormat, New Object() { str3, simpleTypeFullName }) & If((memberDescription.Length > 0), String.Format(CultureInfo.CurrentCulture, Me.DescriptionFormat, New Object() { memberDescription }), String.Empty))
                    Else
                        str = String.Format(CultureInfo.CurrentCulture, Me.PleaseSelectCorrectActivityProperty, New Object() { simpleTypeFullName, str3 })
                    End If
                    str = (str & If((MemberActivityBindTreeNode.MemberName(path).IndexOfAny(New Char() { "["c, "]"c }) <> -1), Me.EditIndex, String.Empty))
                End If
            Else
                str = String.Format(CultureInfo.CurrentCulture, Me.PleaseSelectActivityProperty, New Object() { simpleTypeFullName })
            End If
            Me.helpTextBox.Lines = str.Split(New Char() { ChrW(10) })
        End Sub

        Private Function ValidateExistingPropertyBind() As DialogResult
            Dim selectedActivity As Activity = Me.workflowOutline.SelectedActivity
            Dim selectedMember As PathInfo = Me.workflowOutline.SelectedMember
            Dim propertyPath As String = Me.workflowOutline.PropertyPath
            If ((selectedActivity Is Nothing) OrElse (selectedMember Is Nothing)) Then
                Dim message As String = SR.GetString("Error_BindDialogNoValidPropertySelected", New Object() { Me.GetSimpleTypeFullName(Me.boundType) })
                DesignerHelpers.ShowError(Me.serviceProvider, message)
                Return DialogResult.None
            End If
            Dim propertyType As Type = selectedMember.PropertyType
            Dim service As ITypeProvider = [TryCast](Me.serviceProvider.GetService(GetType(ITypeProvider)),ITypeProvider)
            If ((Not service Is Nothing) AndAlso (Not propertyType Is Nothing)) Then
                Dim type As Type = service.GetType(propertyType.FullName, False)
                propertyType = If((Not type Is Nothing), type, propertyType)
            End If
            If ((Not Me.boundType Is propertyType) AndAlso Not TypeProvider.IsAssignable(Me.boundType, propertyType)) Then
                Dim str3 As String = SR.GetString("Error_BindDialogWrongPropertyType", New Object() { Me.GetSimpleTypeFullName(propertyType), Me.GetSimpleTypeFullName(Me.boundType) })
                DesignerHelpers.ShowError(Me.serviceProvider, str3)
                Return DialogResult.None
            End If
            Dim component As Activity = [TryCast](PropertyDescriptorUtils.GetComponent(Me.context),Activity)
            Dim name As String = Me.context.PropertyDescriptor.Name
            If (((component Is selectedActivity) AndAlso (Not selectedMember Is Nothing)) AndAlso selectedMember.Path.Equals(name, StringComparison.Ordinal)) Then
                DesignerHelpers.ShowError(Me.serviceProvider, SR.GetString("Error_BindDialogCanNotBindToItself"))
                Return DialogResult.None
            End If
            If ((selectedActivity Is Nothing) OrElse (selectedMember Is Nothing)) Then
                Return DialogResult.None
            End If
            Dim bind As New ActivityBind(selectedActivity.QualifiedName, propertyPath)
            Dim manager As New ValidationManager(Me.serviceProvider)
            Dim propertyValidationContext As New PropertyValidationContext(Me.context.Instance, DependencyProperty.FromName(Me.context.PropertyDescriptor.Name, Me.context.Instance.GetType))
            manager.Context.Append(Me.context.Instance)
            Dim errors As ValidationErrorCollection = ValidationHelpers.ValidateProperty(manager, component, bind, propertyValidationContext)
            If (((Not errors Is Nothing) AndAlso (errors.Count > 0)) AndAlso errors.HasErrors) Then
                Dim str5 As String = String.Empty
                Dim i As Integer
                For i = 0 To errors.Count - 1
                    Dim error As ValidationError = errors.Item(i)
                    str5 = (str5 & [error].ErrorText & If((i = (errors.Count - 1)), String.Empty, "; "))
                Next i
                str5 = (SR.GetString("Error_BindDialogBindNotValid") & str5)
                DesignerHelpers.ShowError(Me.serviceProvider, str5)
                Return DialogResult.None
            End If
            Me.binding = bind
            Return DialogResult.OK
        End Function

        Private Function ValidateNewMemberBind(ByVal newMemberName As String) As DialogResult
            Dim component As Activity = [TryCast](PropertyDescriptorUtils.GetComponent(Me.context),Activity)
            If (component Is Nothing) Then
                Dim service As IReferenceService = [TryCast](Me.context.GetService(GetType(IReferenceService)),IReferenceService)
                If (Not service Is Nothing) Then
                    component = [TryCast](service.GetComponent(Me.context.Instance),Activity)
                End If
            End If
            Dim message As String = Nothing
            Try 
                ValidationHelpers.ValidateIdentifier(Me.context, newMemberName)
            Catch obj1 As Object
                message = SR.GetString("Error_InvalidLanguageIdentifier", New Object() { newMemberName })
            End Try
            Dim customActivityType As Type = CustomActivityDesignerHelper.GetCustomActivityType(Me.context)
            Dim supportedLanguage As SupportedLanguages = CompilerHelpers.GetSupportedLanguage(Me.context)
            Dim info As MemberInfo
            For Each info In customActivityType.GetMembers((BindingFlags.NonPublic Or (BindingFlags.Public Or (BindingFlags.Static Or BindingFlags.Instance))))
                If (String.Compare(info.Name, newMemberName, (supportedLanguage = SupportedLanguages.VB), CultureInfo.InvariantCulture) = 0) Then
                    message = SR.GetString("Failure_FieldAlreadyExist")
                    Exit For
                End If
            Next
            If ((message Is Nothing) AndAlso (String.Compare(customActivityType.Name, newMemberName, (supportedLanguage = SupportedLanguages.VB), CultureInfo.InvariantCulture) = 0)) Then
                message = SR.GetString("Failure_FieldAlreadyExist")
            End If
            If (message Is Nothing) Then
                Dim bind As New ActivityBind(ActivityBind.GetRelativePathExpression(Helpers.GetRootActivity(component), component), newMemberName)
                If Not TypeOf Me.context.GetService(GetType(IDesignerHost)) Is IDesignerHost Then
                    Throw New InvalidOperationException(SR.GetString("General_MissingService", New Object() { GetType(IDesignerHost).FullName }))
                End If
                Me.binding = bind
            Else
                DesignerHelpers.ShowError(Me.context, message)
            End If
            If (Not message Is Nothing) Then
                Return DialogResult.None
            End If
            Return DialogResult.OK
        End Function


        ' Properties
        Public ReadOnly Property Binding As ActivityBind
            Get
                Return Me.binding
            End Get
        End Property

        Public ReadOnly Property CreateNew As Boolean
            Get
                Return Me.createNew
            End Get
        End Property

        Public ReadOnly Property CreateNewProperty As Boolean
            Get
                Return Me.createNewProperty
            End Get
        End Property

        Public ReadOnly Property NewMemberName As String
            Get
                Return Me.newMemberName
            End Get
        End Property


        ' Fields
        Private ActivityBindDialogTitleFormat As String
        Private binding As ActivityBind
        Private bindTabControl As TabControl
        Private boundType As Type
        Private buttonTableLayoutPanel As TableLayoutPanel
        Private cancelButton As Button
        Private components As IContainer
        Private context As ITypeDescriptorContext
        Private createField As RadioButton
        Private createNew As Boolean
        Private CreateNewMemberHelpFormat As String
        Private createNewProperty As Boolean
        Private createProperty As RadioButton
        Private DescriptionFormat As String
        Private dummyPanel As Panel
        Private EditIndex As String
        Private existingMemberPage As TabPage
        Private groupBox1 As GroupBox
        Private helpTextBox As TextBox
        Private IncorrectIndexChange As String
        Private memberNameLabel As Label
        Private memberNameTextBox As TextBox
        Private Const MemberTypeFormat As String = "MemberType#{0}"
        Private memberTypes As ImageList
        Private newMemberHelpTextBox As TextBox
        Private newMemberName As String = String.Empty
        Private newMemberPage As TabPage
        Private OKButton As Button
        Private PleaseSelectActivityProperty As String
        Private PleaseSelectCorrectActivityProperty As String
        Private PropertyAssignableFormat As String
        Private serviceProvider As IServiceProvider
        Private workflowOutline As ActivityBindFormWorkflowOutline

        ' Nested Types
        Private Class ActivityBindFormWorkflowOutline
            Inherits WorkflowOutline
            ' Methods
            Public Sub New(ByVal serviceProvider As IServiceProvider, ByVal parent As ActivityBindForm)
                MyBase.New(serviceProvider)
                Me.parent = parent
                MyBase.NeedsExpandAll = False
                AddHandler MyBase.Expanding, New TreeViewCancelEventHandler(AddressOf Me.treeView1_BeforeExpand)
                AddHandler MyBase.TreeView.BeforeLabelEdit, New NodeLabelEditEventHandler(AddressOf Me.TreeView_BeforeLabelEdit)
                AddHandler MyBase.TreeView.AfterLabelEdit, New NodeLabelEditEventHandler(AddressOf Me.TreeView_AfterLabelEdit)
                MyBase.TreeView.LabelEdit = True
                AddHandler MyBase.TreeView.KeyDown, New KeyEventHandler(AddressOf Me.TreeView_KeyDown)
            End Sub

            Public Sub AddMemberKindImages(ByVal memberTypes As ImageList)
                Dim i As Integer
                For i = 0 To memberTypes.Images.Count - 1
                    Dim image As Image = memberTypes.Images.Item(i)
                    MyBase.TreeView.ImageList.Images.Add(String.Format(CultureInfo.InvariantCulture, "MemberType#{0}", New Object() { i }), image)
                Next i
            End Sub

            Private Function CreateMemberNode(ByVal activity As Activity, ByVal pathInfo As PathInfo) As MemberActivityBindTreeNode
                Dim node As New MemberActivityBindTreeNode(activity, pathInfo)
                If node.MayHaveChildNodes Then
                    node.Nodes.Add(New DummyActivityBindTreeNode(activity))
                End If
                Return node
            End Function

            Protected Overrides Function CreateNewNode(ByVal activity As Activity) As WorkflowOutlineNode
                If (Not activity.Enabled OrElse Helpers.IsActivityLocked(activity)) Then
                    Return Nothing
                End If
                Dim node As New ActivityBindTreeNode(activity)
                node.Nodes.Add(New DummyActivityBindTreeNode(activity))
                Return node
            End Function

            Public Sub ExpandRootNode()
                Dim rootNode As TreeNode = MyBase.RootNode
                If (Not rootNode Is Nothing) Then
                    rootNode.Collapse
                    rootNode.Expand
                End If
            End Sub

            Private Function GetMemberNameFromIndexerName(ByVal fullName As String) As String
                Dim index As Integer = fullName.IndexOf("["c)
                If (index <> -1) Then
                    fullName = fullName.Substring(0, index)
                End If
                Return fullName
            End Function

            Private Function IsSamePropertyIndexer(ByVal member1 As MemberInfo, ByVal member2 As MemberInfo) As Boolean
                If ((member1 Is Nothing) OrElse (member2 Is Nothing)) Then
                    Return False
                End If
                Dim info As PropertyInfo = [TryCast](member1,PropertyInfo)
                Dim info2 As PropertyInfo = [TryCast](member2,PropertyInfo)
                Dim info3 As MethodInfo = [TryCast](member1,MethodInfo)
                Dim info4 As MethodInfo = [TryCast](member2,MethodInfo)
                Dim infoArray As ParameterInfo() = If((Not info Is Nothing), info.GetIndexParameters, If((Not info3 Is Nothing), info3.GetParameters, Nothing))
                Dim infoArray2 As ParameterInfo() = If((Not info2 Is Nothing), info2.GetIndexParameters, If((Not info4 Is Nothing), info4.GetParameters, Nothing))
                If (((infoArray Is Nothing) OrElse (infoArray.Length = 0)) OrElse (((infoArray2 Is Nothing) OrElse (infoArray2.Length = 0)) OrElse (infoArray.Length <> infoArray2.Length))) Then
                    Return False
                End If
                Dim i As Integer
                For i = 0 To infoArray.Length - 1
                    If (Not infoArray(i).ParameterType Is infoArray2(i).ParameterType) Then
                        Return False
                    End If
                Next i
                Return True
            End Function

            Protected Overrides Sub OnNodeSelected(ByVal node As WorkflowOutlineNode)
                Me.selectedActivity = If((Not node Is Nothing), node.Activity, Nothing)
                Dim node2 As MemberActivityBindTreeNode = [TryCast](node,MemberActivityBindTreeNode)
                Me.selectedPathInfo = If((Not node2 Is Nothing), node2.PathInfo, Nothing)
                Dim propertyPath As String = Me.PropertyPath
                Me.parent.SelectedActivityChanged(Me.selectedActivity, Me.selectedPathInfo, propertyPath)
            End Sub

            Protected Overrides Sub OnRefreshNode(ByVal node As WorkflowOutlineNode)
                If (Not node.Activity Is Nothing) Then
                    Dim node2 As MemberActivityBindTreeNode = [TryCast](node,MemberActivityBindTreeNode)
                    If (Not node2 Is Nothing) Then
                        node.RefreshNode
                        Dim num As Integer = CInt((node2.MemberKind + DirectCast(CInt(node2.MemberAccessKind), BindMemberKind)))
                        node.ImageIndex = node.SelectedImageIndex = MyBase.TreeView.ImageList.Images.IndexOfKey(String.Format(CultureInfo.InvariantCulture, "MemberType#{0}", New Object() { num }))
                    Else
                        MyBase.OnRefreshNode(node)
                    End If
                End If
            End Sub

            Public Sub SelectActivity(ByVal activity As Activity, ByVal pathInfoList As List([Of] PathInfo))
                Dim parent As WorkflowOutlineNode = MyBase.GetNode(activity)
                If (Not parent Is Nothing) Then
                    parent.Expand
                    If ((Not pathInfoList Is Nothing) AndAlso (pathInfoList.Count > 0)) Then
                        Dim i As Integer
                        For i = 0 To pathInfoList.Count - 1
                            Dim info As PathInfo = pathInfoList.Item(i)
                            Dim node2 As MemberActivityBindTreeNode = Nothing
                            Dim index As Integer = info.Path.IndexOf("["c)
                            If (index <> -1) Then
                                Dim str As String = info.Path.Substring(0, index)
                                If ((parent.Text.Equals(str, StringComparison.Ordinal) AndAlso (i > 0)) AndAlso pathInfoList.Item((i - 1)).Path.Equals(str, StringComparison.Ordinal)) Then
                                    parent = [TryCast](parent.Parent,WorkflowOutlineNode)
                                End If
                            End If
                            Dim node3 As TreeNode
                            For Each node3 In parent.Nodes
                                Dim node4 As MemberActivityBindTreeNode = [TryCast](node3,MemberActivityBindTreeNode)
                                If ((Not node4 Is Nothing) AndAlso node4.PathInfo.Equals(info)) Then
                                    node2 = node4
                                    Exit For
                                End If
                                If (((Not node4 Is Nothing) AndAlso node4.Text.Contains("[")) AndAlso info.Path.Contains("[")) Then
                                    Dim memberNameFromIndexerName As String = Me.GetMemberNameFromIndexerName(info.Path)
                                    Dim b As String = Me.GetMemberNameFromIndexerName(node4.Text)
                                    If (String.Equals(memberNameFromIndexerName, b, StringComparison.Ordinal) AndAlso Me.IsSamePropertyIndexer(info.MemberInfo, node4.PathInfo.MemberInfo)) Then
                                        node2 = node4
                                        node4.PathInfo = info
                                        node4.Text = MemberActivityBindTreeNode.MemberName(info.Path)
                                        Exit For
                                    End If
                                End If
                            Next
                            If (node2 Is Nothing) Then
                                Exit For
                            End If
                            parent = node2
                            parent.Expand
                        Next i
                    End If
                    MyBase.TreeView.SelectedNode = parent
                    Dim timer As New Timer
                    AddHandler timer.Tick, New EventHandler(AddressOf Me.timer_Tick)
                    timer.Interval = 50
                    timer.Start
                End If
            End Sub

            Private Sub timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
                Dim timer As Timer = [TryCast](sender,Timer)
                If (Not timer Is Nothing) Then
                    timer.Stop
                    RemoveHandler timer.Tick, New EventHandler(AddressOf Me.timer_Tick)
                End If
                If (Not MyBase.TreeView.SelectedNode Is Nothing) Then
                    MyBase.TreeView.SelectedNode.EnsureVisible
                End If
                MyBase.Focus
            End Sub

            Private Sub TreeView_AfterLabelEdit(ByVal sender As Object, ByVal e As NodeLabelEditEventArgs)
                Dim text As String = e.Node.Text
                Dim label As String = e.Label
                If (([text] Is Nothing) OrElse (label Is Nothing)) Then
                    e.CancelEdit = True
                Else
                    Dim node As MemberActivityBindTreeNode = [TryCast](e.Node,MemberActivityBindTreeNode)
                    Dim flag As Boolean = False
                    If ((label.IndexOf("[", StringComparison.Ordinal) = -1) OrElse Not label.EndsWith("]", StringComparison.Ordinal)) Then
                        flag = True
                    Else
                        Dim str3 As String = [text].Substring(0, [text].IndexOf("[", StringComparison.Ordinal))
                        Dim str4 As String = label.Substring(0, label.IndexOf("[", StringComparison.Ordinal))
                        flag = Not str3.Equals(str4, StringComparison.Ordinal)
                    End If
                    If Not flag Then
                        Dim parent As ActivityBindTreeNode = [TryCast](node.Parent,ActivityBindTreeNode)
                        Dim node3 As MemberActivityBindTreeNode = [TryCast](parent,MemberActivityBindTreeNode)
                        Dim activityType As Type = If((Not node3 Is Nothing), node3.PathInfo.PropertyType, Me.parent.GetActivityType(parent.Activity))
                        Dim list As List([Of] PathInfo) = Me.parent.ParseStringPath(activityType, label)
                        If ((list Is Nothing) OrElse (list.Count = 0)) Then
                            flag = True
                        Else
                            Dim info As PathInfo = list.Item((list.Count - 1))
                            If info.Path.Equals(label, StringComparison.Ordinal) Then
                                node.PathInfo = info
                            Else
                                flag = True
                            End If
                        End If
                    End If
                    If flag Then
                        DesignerHelpers.ShowError(Me.parent.serviceProvider, String.Format(CultureInfo.CurrentCulture, Me.parent.IncorrectIndexChange, New Object() { label }))
                        e.CancelEdit = True
                    End If
                End If
            End Sub

            Private Sub TreeView_BeforeLabelEdit(ByVal sender As Object, ByVal e As NodeLabelEditEventArgs)
                Dim node As MemberActivityBindTreeNode = [TryCast](e.Node,MemberActivityBindTreeNode)
                e.CancelEdit = (((node Is Nothing) OrElse Not node.Text.Contains("[")) OrElse Not node.Text.Contains("]"))
            End Sub

            Private Sub TreeView_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
                If ((e.KeyCode = Keys.F2) AndAlso (Not MyBase.TreeView.SelectedNode Is Nothing)) Then
                    MyBase.TreeView.SelectedNode.BeginEdit
                    e.Handled = True
                    e.SuppressKeyPress = True
                End If
            End Sub

            Private Sub treeView1_BeforeExpand(ByVal sender As Object, ByVal e As TreeViewCancelEventArgs)
                Dim node As ActivityBindTreeNode = [TryCast](e.Node,ActivityBindTreeNode)
                If (((Not node Is Nothing) AndAlso (node.Nodes.Count > 0)) AndAlso TypeOf node.Nodes.Item(0) Is DummyActivityBindTreeNode) Then
                    Dim node2 As MemberActivityBindTreeNode = [TryCast](node,MemberActivityBindTreeNode)
                    Dim list As List([Of] PathInfo) = Me.parent.PopulateAutoCompleteList(node.Activity, If((Not node2 Is Nothing), node2.PathInfo, Nothing))
                    Dim list2 As New List([Of] TreeNode)
                    Dim info As PathInfo
                    For Each info In list
                        Dim nodeToUpdate As MemberActivityBindTreeNode = Me.CreateMemberNode(node.Activity, info)
                        If (Not nodeToUpdate Is Nothing) Then
                            MyBase.RefreshNode(nodeToUpdate, False)
                            list2.Add(nodeToUpdate)
                        End If
                    Next
                    MyBase.TreeView.BeginUpdate
                    Try 
                        node.Nodes.RemoveAt(0)
                        e.Node.Nodes.AddRange(list2.ToArray)
                    Finally
                        MyBase.TreeView.EndUpdate
                    End Try
                End If
            End Sub


            ' Properties
            Public ReadOnly Property PropertyPath As String
                Get
                    Dim selectedNode As MemberActivityBindTreeNode = [TryCast](MyBase.TreeView.SelectedNode,MemberActivityBindTreeNode)
                    Dim str As String = String.Empty
                    Do While (Not selectedNode Is Nothing)
                        str = If((str.Length = 0), selectedNode.Text, (selectedNode.Text & "." & str))
                        selectedNode = [TryCast](selectedNode.Parent,MemberActivityBindTreeNode)
                    Loop
                    Return str
                End Get
            End Property

            Public ReadOnly Property SelectedActivity As Activity
                Get
                    Return Me.selectedActivity
                End Get
            End Property

            Public ReadOnly Property SelectedMember As PathInfo
                Get
                    Return Me.selectedPathInfo
                End Get
            End Property


            ' Fields
            Private parent As ActivityBindForm
            Private selectedActivity As Activity
            Private selectedPathInfo As PathInfo
        End Class

        Private Class ActivityBindTreeNode
            Inherits WorkflowOutlineNode
            ' Methods
            Public Sub New(ByVal activity As Activity)
                MyBase.New(activity)
            End Sub

        End Class

        Friend Enum BindMemberAccessKind
            ' Fields
            Internal = 1
            [Private] = 3
            [Protected] = 2
            [Public] = 0
        End Enum

        Friend Enum BindMemberKind
            ' Fields
            Constant = 8
            [Delegate] = &H10
            [Event] = 12
            Field = 0
            Index = 20
            [Property] = 4
        End Enum

        Private Class DummyActivityBindTreeNode
            Inherits WorkflowOutlineNode
            ' Methods
            Public Sub New(ByVal activity As Activity)
                MyBase.New(activity)
            End Sub

        End Class

        Private Class MemberActivityBindTreeNode
            Inherits ActivityBindTreeNode
            ' Methods
            Public Sub New(ByVal activity As Activity, ByVal pathInfo As PathInfo)
                MyBase.New(activity)
                Me.kind = BindMemberKind.Property
                Me.pathInfo = pathInfo
                Dim str As String = MemberActivityBindTreeNode.MemberName(Me.PathInfo.Path)
                If TypeOf Me.pathInfo.MemberInfo Is EventInfo Then
                    Me.kind = BindMemberKind.Event
                    Me.accessKind = BindMemberAccessKind.Public
                ElseIf TypeOf Me.pathInfo.MemberInfo Is FieldInfo Then
                    Dim memberInfo As FieldInfo = [TryCast](Me.pathInfo.MemberInfo,FieldInfo)
                    If (((memberInfo.Attributes And FieldAttributes.Static) <> FieldAttributes.PrivateScope) AndAlso ((memberInfo.Attributes And FieldAttributes.Literal) <> FieldAttributes.PrivateScope)) Then
                        Me.kind = BindMemberKind.Constant
                    ElseIf TypeProvider.IsAssignable(GetType(Delegate), memberInfo.FieldType) Then
                        Me.kind = BindMemberKind.Delegate
                    Else
                        Me.kind = BindMemberKind.Field
                    End If
                    Me.accessKind = If(memberInfo.IsPublic, BindMemberAccessKind.Public, If(memberInfo.IsFamily, BindMemberAccessKind.Internal, If(memberInfo.IsPrivate, BindMemberAccessKind.Private, BindMemberAccessKind.Protected)))
                ElseIf TypeOf Me.pathInfo.MemberInfo Is PropertyInfo Then
                    Me.kind = BindMemberKind.Property
                    Dim info1 As MemberInfo = Me.pathInfo.MemberInfo
                    Me.accessKind = BindMemberAccessKind.Public
                ElseIf (str.IndexOfAny("[]".ToCharArray) <> -1) Then
                    Me.kind = BindMemberKind.Index
                    Me.accessKind = BindMemberAccessKind.Public
                Else
                    Me.kind = BindMemberKind.Property
                    Me.accessKind = BindMemberAccessKind.Public
                End If
            End Sub

            Friend Shared Function MemberName(ByVal path As String) As String
                Dim str As String = path
                Dim num As Integer = str.LastIndexOf("."c)
                Return If(((num <> -1) AndAlso ((num + 1) < str.Length)), str.Substring((num + 1)), str)
            End Function

            Public Overrides Sub RefreshNode()
                MyBase.RefreshNode
                MyBase.Text = MemberActivityBindTreeNode.MemberName(Me.PathInfo.Path)
                MyBase.ForeColor = Color.DarkBlue
            End Sub


            ' Properties
            Public ReadOnly Property MayHaveChildNodes As Boolean
                Get
                    Dim type As Type = If((Not Me.pathInfo Is Nothing), Me.pathInfo.PropertyType, Nothing)
                    If (type Is Nothing) Then
                        Return False
                    End If
                    Return ((Not ActivityBindForm.IsTypePrimitive(type) AndAlso Not TypeProvider.IsAssignable(GetType(Delegate), type)) AndAlso (Not type Is GetType(Object)))
                End Get
            End Property

            Public ReadOnly Property MemberAccessKind As BindMemberAccessKind
                Get
                    Return Me.accessKind
                End Get
            End Property

            Public ReadOnly Property MemberKind As BindMemberKind
                Get
                    Return Me.kind
                End Get
            End Property

            Public Property PathInfo As PathInfo
                Get
                    Return Me.pathInfo
                End Get
                Set(ByVal value As PathInfo)
                    Me.pathInfo = value
                End Set
            End Property


            ' Fields
            Private accessKind As BindMemberAccessKind
            Private kind As BindMemberKind
            Private pathInfo As PathInfo
        End Class

        Private Class PathInfo
            ' Methods
            Public Sub New(ByVal path As String, ByVal memberInfo As MemberInfo, ByVal propertyType As Type)
                If String.IsNullOrEmpty(path) Then
                    Throw New ArgumentNullException("path")
                End If
                If (propertyType Is Nothing) Then
                    Throw New ArgumentNullException("propertyType")
                End If
                If (memberInfo Is Nothing) Then
                    Throw New ArgumentNullException("memberInfo")
                End If
                Me.path = path
                Me.propertyType = propertyType
                Me.memberInfo = memberInfo
            End Sub

            Public Overrides Function Equals(ByVal obj As Object) As Boolean
                Dim info As PathInfo = [TryCast](obj,PathInfo)
                If (info Is Nothing) Then
                    Return False
                End If
                Return Me.path.Equals(info.path, StringComparison.Ordinal)
            End Function

            Public Overrides Function GetHashCode() As Integer
                Return Me.path.GetHashCode
            End Function

            Public Overrides Function ToString() As String
                Return Me.path
            End Function


            ' Properties
            Public ReadOnly Property MemberInfo As MemberInfo
                Get
                    Return Me.memberInfo
                End Get
            End Property

            Public ReadOnly Property Path As String
                Get
                    Return Me.path
                End Get
            End Property

            Public ReadOnly Property PropertyType As Type
                Get
                    Return Me.propertyType
                End Get
            End Property


            ' Fields
            Private memberInfo As MemberInfo
            Private path As String
            Private propertyType As Type
        End Class
    End Class
End Namespace

